#!/usr/bin/env python
from __future__ import division

from pygame import draw, Rect, transform
import math
import random

import angles
from vectors import Vector, AngleVector
import collision

from objects import Object
import paths

class Unit(Object):
	render_layer = 1
	
	collisions = None
	radius = 5
	
	def __init__(self, game, path, path_deviation, angle=None):		
		self.game = game
		
		self.path = path
		self.path_deviation = path_deviation
		self.angle = angle
		
		self._remove = False
		
		self.next_path = self.path.next_node()
		
		start_radius = (self.path.position, self.path_deviation)
		self.position = Vector(*angles.random_point_in_circle(start_radius))
		self.circle = collision.Circle(self.position, self.radius)
		
		self.colour = (random.randint(128,255),random.randint(128,255),random.randint(128,255))
		
		self.max_speed = random.uniform(0.5, 1)
		self.speed = self.max_speed
		
		self.turn_speed = self.speed * random.uniform(angles.FULL_CIRCLE / 32, angles.FULL_CIRCLE / 16)
		
		self.new_destination()
		self.health = 1
		
		self.target = None
		
		if self.angle == None:
			self.angle = angles.angle_between_points(self.position, self.target_position)
		
	def remove(self):
		if not self._remove:
			self.game.remove_object(self)
		
		self._remove = True

	def update(self):
		x, y = self.position
		
		self.circle.move_ip(self.position)
		self.game.collision_layers["units"].add(self, self.circle.rect())
		
		if self.path.movement == paths.MOVE:
			self.speed = self.max_speed
			
			self.turn_to_target(self.target_position)
			self.move()
			
			target_x, target_y = self.target_position
			
			if (target_y - y) ** 2 + (target_x - x) ** 2 <= self.path_deviation ** 2:				
				self.path = self.next_path
				
				if self.path.children:
					self.next_path = self.path.next_node()
					self.new_destination()
			
		elif self.path.movement == paths.WAIT:
			self.speed = 0
			
			if self.path.action != paths.IGNORE:
				self.turn_to_target(self.path.target.position)
		
		if self.path.action == paths.ATTACK:
			if self.path.target.health > 0:
				self.attack(self.path.target)
			else:
				self.target = None
				self.path.action = paths.IGNORE
				self.path.movement = paths.MOVE
				
		elif self.path.action == paths.DIE:
			self.remove()
		elif self.path.action == paths.IGNORE:
			self.target = None
		
		if self.health <= 0: 
			self.remove()
		
	def draw(self, surface):
		x, y = (int(coord) for coord in self.position)
		
		"""draw.circle(surface, self.colour, (x, y), 5)
		draw.line(surface, self.colour, (x, y), (x + 10 * math.cos(self.angle), y + 10 * math.sin(self.angle)))"""
		
		rotate = transform.rotozoom(self.graphic, math.degrees(-self.angle), 1)
		width, height = rotate.get_size()
	
		surface.blit(rotate, (x - width // 2, y - height // 2))
		
		"""if self.health > 0:
			draw.rect(surface, (0, 255, 0), Rect(x - 10, y + 8, 20 * self.health, 3))"""
		
		if self.target:
			a = angles.random_point_in_circle((self.target.position, 32))
			
			draw.line(surface, (255, 0, 0), tuple(self.position), tuple(a))
	
	def move(self):
		self.position += AngleVector(self.angle, self.speed)
	
	def turn_to_target(self, position):			
		target_angle = angles.angle_between_points(self.position, position)
		
		direction = angles.direction_to_angle(self.angle, target_angle)
		shortest = min(angles.rotations_to_angle(self.angle, target_angle))
				
		if self.turn_speed > shortest: 
			self.angle = target_angle
		else:
			self.angle += angles.clamp_angle(self.turn_speed * direction)
				
	def new_destination(self):
		target_radius = (self.next_path.position, self.path_deviation)
		self.target_position = angles.random_point_in_circle(target_radius)
		
	def attack(self, target):
		self.crap_attack(target)
		
	def crap_attack(self, target):
		self.target = target
		self.target.health -= 0.001

class Infantry(Unit):
	graphic = "units/infantry.png"

class Commando(Infantry):
	def __init__(self, game, path, path_deviation, angle=-1):
		super(Commando, self).__init__(game, path, path_deviation, angle)
		
		self.max_speed = self.speed = random.uniform(2, 3)

class Tank(Unit):
	graphic = "units/tank.png"
	radius = 24
		
from graphics import graphics, request_replace
request_replace(Infantry, Commando, Tank)
